<?php
/**
 * Nweb Framework
 *
 * This script is protected by copyright. It's use, copying, modification
 * and distribution without written consent of the author is prohibited.
 *
 * @category    source
 * @package     pl.nweb.framework.application.controller
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2011 Krzysztof Kardasz
 * @license     http://www.gnu.org/licenses/lgpl-3.0.txt  GNU Lesser General Public
 * @version     3.0 $Id$
 * @link        http://code.google.com/p/nweb-framework/
 * @link        http://framework.nweb.pl
 */

namespace pl\nweb\framework\application;

/**
 * Kontroler aplikacji
 *
 * @category    source
 * @package     pl.nweb.framework.application.controller
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2011 Krzysztof Kardasz
 * @version     3.0 $Id$
 */
abstract class Controller
{
    /**
     * Obiekt żądanie
     *
     * @var \pl\nweb\framework\Request
     */
    private $_request = null;

    /**
     * Obiekt odpowiedzi
     *
     * @var \pl\nweb\framework\Response
     */
    private $_response = null;

    /**
     * Obiekt menadżera konfiguracji
     *
     * @var null|\pl\nweb\framework\Config
     */
    private $_config = null;

    /**
     * Obiekt rejestru
     *
     * @var null|\pl\nweb\framework\Registry
     */
    private $_registry = null;

    /**
     * Konstruktor
     *
     * @return void
     */
    final public function __construct ()
    {
        $this->_setup();
    }

    /**
     * Konfiguracja obiektów
     *
     * @return void
     */
    protected function _setup () {}

    /**
     * Inicjacja
     *
     * @return void
     */
    protected function _init () {}

    /**
     * Zdarzenie, przed realizacją żądania
     *
     * @return void
     */
    protected function _preDispatch () {}

    /**
     * Zdarzenie, po realizacji żądania
     *
     * @return void
     */
    protected function _postDispatch () {}

    /**
     * Wykonuje żądanie
     *
     * @param \pl\nweb\framework\Request obiekt żądania
     * @param \pl\nweb\framework\Response obiekt odpowiedzi
     * @return mixed action results
     * @throws \pl\nweb\framework\application\dispatcher\Exception
     */
    public function dispatch (\pl\nweb\framework\Request $request, \pl\nweb\framework\Response $response)
    {
        $this->_request  = $request;
        $this->_response = $response;

        $action = $this->_request->getAction();
        $action = strtolower($action) . 'Action';

        if(method_exists($this, $action)) {
            $this->_preDispatch();
            $results = $this->{$action}();
            $this->_postDispatch();
            return $results;
        } else {
            throw new dispatcher\Exception ('Action "' . $this->_request->getAction() . '" not found');
        }
    }

    /**
     * Zwraca obiekt żądania
     *
     * @return \pl\nweb\framework\Request
     */
    protected function getRequest()
    {
        return $this->_request;
    }

    /**
     * Zwraca obiekt odpowiedzi
     *
     * @return \pl\nweb\framework\Response
     */
    protected function getResponse()
    {
        return $this->_response;
    }

    /**
     * Zwraca obiekt menadżera konfiguracji (w przypadku braku podania argumentów) lub konfigurację (jeśli podano argumenty)
     *
     * @param null|string $name nazwa pliku konfiguracyjnego
     * @param null|string $format format pliku konfiguracyjnego (php|ini|xml|yaml)
     * @return \pl\nweb\framework\Config
     */
    public function getConfig ()
    {
        $args = func_get_args();
        if(!empty($args)) {
            return call_user_func_array (array($this->_config, 'getConfig'), $args);
        }
        return $this->_config;
    }

    /**
     * Przekierowanie żądania
     *
     * @param string $module moduł
     * @param string $controller kontroler
     * @param string $action akcja
     * @param array $params parametry
     * @return void
     */
    protected function _forward ($action = null, $controller = null, $module = null, $params = array())
    {
        $fwd = false;
        if(!empty($action) && $action != $this->getRequest()->getAction()) {
            $fwd = true;
            $this->getRequest()->setAction($action);
        }

        if(!empty($controller) && $controller != $this->getRequest()->getController()) {
            $fwd      = true;
            $this->getRequest()->setController($controller);
        }

        if(!empty($module) && $module != $this->getRequest()->getModule()) {
            $fwd      = true;
            $this->getRequest()->setModule($module);
        }

        if($fwd) {
            if(!empty($params)) {
                $this->getRequest()->setParams($params);
            }

            // $this->_request->setForwarded(true);
            $this->getRequest()->setDispatched(false);
        }
    }

    /**
     * Zdalne uruchamianie zewnętrznej aplikacji
     *
     * @param string $app nazwa aplikacji
     * @param string $bootstrap nazwa klasy bootstrap
     * @param array $params parametry żądania
     * @return \Gbm\Lib\Application\Bootstrap
     * @throws Dispatcher\Exception
     */
    protected function remoteRun ($app, $bootstrap, array $params)
    {
        // return \Gbm\Lib\Application\Bootstrap\Remote::run($app, $bootstrap, $params);
    }
}